/*******************************************************************************
 * Copyright (c) 2022 - 2025 NVIDIA Corporation & Affiliates.                  *
 * All rights reserved.                                                        *
 *                                                                             *
 * This source code and the accompanying materials are made available under    *
 * the terms of the Apache License 2.0 which accompanies this distribution.    *
 ******************************************************************************/

// clang-format off
// RUN: cudaq-quake  %s | cudaq-opt --decomposition=enable-patterns="RxAdjToRx,RyAdjToRy,RzAdjToRz" | cudaq-translate --convert-to=openqasm2 | FileCheck %s
// clang-format on

#include <cudaq.h>
#include <iostream>
#include <unordered_set>

struct kernel {
  void operator()() __qpu__ {
    double theta = 0.67;
    cudaq::qvector qubits(6);

    x(qubits[5]);
    h<cudaq::ctrl>(qubits[4], qubits[5]);
    rx<cudaq::adj>(theta, qubits[4]);

    x(qubits[3]);
    h<cudaq::ctrl>(qubits[2], qubits[3]);
    ry<cudaq::adj>(theta, qubits[2]);

    x(qubits[1]);
    h<cudaq::ctrl>(qubits[0], qubits[1]);
    rz<cudaq::adj>(theta, qubits[0]);

    mz(qubits);
  }
};


int main() {
  auto counts = cudaq::sample(kernel{});
  counts.dump();
}

// CHECK:  // Code generated by NVIDIA's nvq++ compiler
// CHECK:  OPENQASM 2.0;

// CHECK:  include "qelib1.inc";

// CHECK:  gate ZN6kernelclEv(param0)  {
// CHECK:  }

// CHECK:  qreg var0[6];
// CHECK:  x var0[5];
// CHECK:  ch var0[4], var0[5];
// CHECK:  rx(-6.700000e-01) var0[4];
// CHECK:  x var0[3];
// CHECK:  ch var0[2], var0[3];
// CHECK:  ry(-6.700000e-01) var0[2];
// CHECK:  x var0[1];
// CHECK:  ch var0[0], var0[1];
// CHECK:  rz(-6.700000e-01) var0[0];
// CHECK:  creg var7[6];
// CHECK:  measure var0 -> var7;
